﻿namespace BathroomLocator.Services.Infrastructure
{
	using System;
	using System.Globalization;
	using System.Web.Mvc;
	using System.Web.Security;
	using BathroomLocator.Services.MembershipWrappers;

	public sealed class CustomAuthorizeAttribute : AuthorizeAttribute
	{
		private RoleProvider roleProvider;

		public RoleProvider RoleProvider
		{
			get
			{
				if (this.roleProvider == null)
				{
					this.roleProvider = new RoleProviderWrapper();
				}

				return this.roleProvider;
			}

			private set
			{
				this.roleProvider = value;
			}
		}

		protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
		{
			var cookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
			var loginUrl = string.Format(CultureInfo.InvariantCulture, "~/Account/LogOn?returnUrl={0}", filterContext.HttpContext.Request.RawUrl);

			if (cookie == null)
			{
				filterContext.Result = new RedirectResult(loginUrl);
			}
			else
			{
				FormsAuthenticationTicket ticket = null;

				try
				{
					ticket = FormsAuthentication.Decrypt(cookie.Value);
				}
				catch (ArgumentException)
				{
					filterContext.Result = new RedirectResult(loginUrl);
				}

				if (ticket != null)
				{
					var userName = new FormsIdentity(ticket).Name;

					if (!this.RoleProvider.IsUserInRole(userName, this.Roles))
					{
						filterContext.Result = new RedirectResult("~/Account/Unauthorized");
					}
				}
			}
		}
	}
}